<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram</title>
</head>
<body>
    <canvas id="physicsCanvas" width="600" height="300"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');
        
        // Clear canvas with a white background
        ctx.fillStyle = 'white';
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        // Set drawing styles
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 2;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';

        // --- Helper Functions ---

        /**
         * Draws an arrow from (fromx, fromy) to (tox, toy).
         * @param {CanvasRenderingContext2D} context The rendering context.
         * @param {number} fromx The x-coordinate of the start point.
         * @param {number} fromy The y-coordinate of the start point.
         * @param {number} tox The x-coordinate of the end point.
         * @param {number} toy The y-coordinate of the end point.
         * @param {number} [headlen=10] The length of the arrow head.
         */
        function drawArrow(context, fromx, fromy, tox, toy, headlen = 10) {
            const dx = tox - fromx;
            const dy = toy - fromy;
            const angle = Math.atan2(dy, dx);
            context.beginPath();
            context.moveTo(fromx, fromy);
            context.lineTo(tox, toy);
            context.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
            context.moveTo(tox, toy);
            context.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
            context.stroke();
        }

        /**
         * Draws a spring between two points on a horizontal line.
         * @param {CanvasRenderingContext2D} context The rendering context.
         * @param {number} x1 The starting x-coordinate.
         * @param {number} y The y-coordinate (constant).
         * @param {number} x2 The ending x-coordinate.
         * @param {number} coils The number of coils/teeth in the spring.
         * @param {number} amplitude The height of the spring coils from the center line.
         */
        function drawSpring(context, x1, y, x2, coils, amplitude) {
            const length = x2 - x1;
            const toothWidth = length / coils;
            context.beginPath();
            context.moveTo(x1, y);
            for (let i = 0; i < coils; i++) {
                const startX = x1 + i * toothWidth;
                // Draw one tooth: up then down
                context.lineTo(startX + toothWidth / 2, y - amplitude);
                context.lineTo(startX + toothWidth, y);
            }
            context.stroke();
        }


        // --- Main Drawing Logic ---

        // Define base coordinates and dimensions
        const baseY = 150;
        const originX = 80;
        const blockWidth = 50;
        const blockHeight = 40;
        const springLength = 70;
        const springAmplitude = 8;
        const springCoils = 6;
        const blockGap = springLength + blockWidth;

        // Calculate positions of blocks
        const blockAx = originX + 50;
        const blockBx = blockAx + blockGap;
        const blockCx = blockBx + blockGap;

        // 1. Draw Coordinate Axes
        ctx.beginPath();
        // Y-axis line
        ctx.moveTo(originX, 70);
        ctx.lineTo(originX, 200);
        ctx.stroke();
        // Y-axis arrow
        drawArrow(ctx, originX, 70, originX, 60);

        // X-axis line (serves as the surface for the blocks)
        drawArrow(ctx, originX, baseY, 560, baseY);

        // 2. Draw Blocks
        ctx.font = '24px serif';
        // Block A
        ctx.strokeRect(blockAx, baseY - blockHeight / 2, blockWidth, blockHeight);
        ctx.fillText('A', blockAx + blockWidth / 2, baseY);
        // Block B
        ctx.strokeRect(blockBx, baseY - blockHeight / 2, blockWidth, blockHeight);
        ctx.fillText('B', blockBx + blockWidth / 2, baseY);
        // Block C
        ctx.strokeRect(blockCx, baseY - blockHeight / 2, blockWidth, blockHeight);
        ctx.fillText('C', blockCx + blockWidth / 2, baseY);

        // 3. Draw Springs
        drawSpring(ctx, blockAx + blockWidth, baseY, blockBx, springCoils, springAmplitude);
        drawSpring(ctx, blockBx + blockWidth, baseY, blockCx, springCoils, springAmplitude);

        // 4. Draw Labels
        ctx.font = '22px serif';
        // Origin 'O'
        ctx.fillText('O', originX - 15, baseY + 15);
        // Axis 'x'
        ctx.fillText('x', 570, baseY);
        // Force 'F'
        const forceY = baseY - blockHeight / 2 - 20;
        drawArrow(ctx, originX, forceY, blockAx - 5, forceY);
        ctx.fillText('F', originX - 20, forceY);

        // 5. Draw Caption
        ctx.font = '20px serif';
        ctx.fillText('Fig. 1.95.', canvas.width / 2, 270);

    </script>
</body>
</html>